package com.qsw.fileoperatelib.test;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;

import com.qsw.fileoperatelib.FileOperateUtil;
import com.qsw.fileoperatelib.R;
import com.qsw.fileoperatelib.encode.EncodeUtil;
import com.qsw.fileoperatelib.iedata.BIEDataUtil;
import com.qsw.fileoperatelib.test.bean.FolTestExcelBean;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import jxl.read.biff.BiffException;
import jxl.write.WriteException;

public class FOLTestActivity extends Activity {
    private static final String TAG = "TAG_FOLTestActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fol_activity_foltest);

//        testExcel();
//        testZip();
//        testPatch();
//        testIEData();
        testEncodeReversal();
    }

    private void testExcel() {
        List<FolTestExcelBean> folTestExcelBeanList = new ArrayList<>();
        folTestExcelBeanList.add(new FolTestExcelBean(11, 12, "str11", "str12"));
        folTestExcelBeanList.add(new FolTestExcelBean(21, 22, "str21", "str22"));
        folTestExcelBeanList.add(new FolTestExcelBean(31, 32, "str31", "str32"));
        folTestExcelBeanList.add(new FolTestExcelBean(41, 42, "str41", "str42"));
        folTestExcelBeanList.add(new FolTestExcelBean(51, 52, "str51", "str52"));
        folTestExcelBeanList.add(new FolTestExcelBean(61, 62, "str61", "str62"));

        String testFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "TestFolder";
        try {
            boolean writeToExcelResult = FileOperateUtil.writeToExcel(folTestExcelBeanList, testFolderPath, System.currentTimeMillis(), "signName");
            Log.d(TAG, "testExcel writeToExcelResult = " + writeToExcelResult);
            File readExcelFile = new File(testFolderPath + File.separator + "20240909_130820_signName.xls");
            try {
                List<FolTestExcelBean> readList = FileOperateUtil.readFromExcel(readExcelFile, FolTestExcelBean.class);
                for (FolTestExcelBean folTestExcelBean : readList) {
                    Log.d(TAG, "testExcel readFromExcel = " + folTestExcelBean);
                }
            } catch (IllegalAccessException | InstantiationException e) {
                e.printStackTrace();
            }
        } catch (WriteException | IOException | BiffException e) {
            e.printStackTrace();
        }
    }

    private void testZip() {
        String testFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "TestFolder";
        File readExcelFile = new File(testFolderPath + File.separator + "20240909_130820_signName.xls");
        try {
            FileOperateUtil.zip(readExcelFile.getAbsolutePath(), testFolderPath + File.separator + "test.zip", true);
            FileOperateUtil.unzip(testFolderPath + File.separator + "test.zip", testFolderPath + File.separator + "test");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void testPatch() {
        String testFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "TestFolder";
        File oldFile = new File(testFolderPath + File.separator + "1.xls");
        File newFile = new File(testFolderPath + File.separator + "2.xls");
        File npatchFile = new File(testFolderPath + File.separator + "patch.p");
        FileOperateUtil.patchFile(oldFile.getAbsolutePath(), newFile.getAbsolutePath(), npatchFile.getAbsolutePath());
    }

    private void testIEData() {
        String testFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "TestFolder";
        File oldFile = new File(testFolderPath + File.separator + "1.apk");
        List<String> dataList = new ArrayList<>();
        dataList.add("测试信息1");
        dataList.add("测试信息22");
        dataList.add("测试信息333");
        dataList.add("444abc");
        dataList.add("1-2_3.4*5+6");
        try {
            long startTime = System.currentTimeMillis();
            final int[] percent = {0};
            final BIEDataUtil.IEType[] iEType = {null};
            File injectFile = FileOperateUtil.injectEnd(oldFile, dataList, testFolderPath, "lpth", true, new BIEDataUtil.OnProgressChangeListener() {
                int innerPercent = 0;
                BIEDataUtil.IEType innerIeType = null;

                @Override
                public void onProgressChange(BIEDataUtil.IEType ieType, long ieTypeCurrProgress, long ieTypeMaxProgress, long totalCurrProgress, long totalMaxProgress) {
                    innerPercent = (int) (ieTypeCurrProgress * 100F / ieTypeMaxProgress);
                    innerIeType = ieType;
                    if (innerIeType != iEType[0] || innerPercent != percent[0]) {
                        percent[0] = innerPercent;
                        iEType[0] = innerIeType;
                        Log.d(TAG, "injectProgress = " + ieType.name() + " : " + ieTypeCurrProgress + " : " + ieTypeMaxProgress + " : percent = " + percent[0]);
                    }
//                    Log.d(TAG, "injectProgress = " + ieType.name() + " : " + ieTypeCurrProgress + " : " + ieTypeMaxProgress);
                }
            });
            Log.d(TAG, "injectResult = " + (injectFile == null ? "null" : injectFile.getAbsolutePath()));
            percent[0] = 0;
            iEType[0] = null;
            BIEDataUtil.ReadDataAndRecoverResult readDataAndRecoverResult =
                    FileOperateUtil.readDataAndRecoverEnd(injectFile, testFolderPath, "rec", true, true, new BIEDataUtil.OnProgressChangeListener() {
                        int innerPercent = 0;
                        BIEDataUtil.IEType innerIeType = null;

                        @Override
                        public void onProgressChange(BIEDataUtil.IEType ieType, long ieTypeCurrProgress, long ieTypeMaxProgress, long totalCurrProgress, long totalMaxProgress) {
                            innerPercent = (int) (ieTypeCurrProgress * 100F / ieTypeMaxProgress);
                            innerIeType = ieType;
                            if (innerIeType != iEType[0] || innerPercent != percent[0]) {
                                percent[0] = innerPercent;
                                iEType[0] = innerIeType;
                                Log.d(TAG, "readAndRecoverProgress = " + ieType.name() + " : " + ieTypeCurrProgress + " : " + ieTypeMaxProgress + " : percent = " + percent[0]);
                            }
//                            Log.d(TAG, "readProgress = " + ieType.name() + " : " + ieTypeCurrProgress + " : " + ieTypeMaxProgress);
                        }
                    });
            for (String readDatum : readDataAndRecoverResult.getReadDataResult().getReadData()) {
                Log.d(TAG, "readDatum = " + (readDatum == null ? "null" : readDatum));
            }
            Log.d(TAG, "readDataResult.getRecoverFilePath() = " + readDataAndRecoverResult.getRecoverFilePath());
            Log.d(TAG, "totalTime = " + (System.currentTimeMillis() - startTime));
        } catch (IOException | NoSuchAlgorithmException e) {
            Log.d(TAG, "injectResult e = " + e.getMessage());
            e.printStackTrace();
        }
    }

    private void testEncodeReversal() {
        String testFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "TestFolder";
        File file = new File(testFolderPath + File.separator + "Crane_release_LETECH_TJ_V1.1.25.apk");


        long[] serKey = new long[]{2, 400, 7, 800, 9, file.length() / 2 - 1, file.length() - 1};

        try {
            /*FileInputStream fis = new FileInputStream(file);
            byte[] bytes = new byte[1024];
            long length;
            while ((length = fis.read(bytes)) > 0) {
                Log.d(TAG, "read1: " + bytesToHexCommonPrint(bytes, (int) length));
            }
            fis.close();*/

            boolean result = EncodeUtil.encodeDecodeReversal(file, serKey);
            Log.d(TAG, "testEncodeReversal file.length = " + file.length() + "; result = " + result);

            /*fis = new FileInputStream(file);
            while ((length = fis.read(bytes)) > 0) {
                Log.d(TAG, "read2: " + bytesToHexCommonPrint(bytes, (int) length));
            }
            fis.close();*/
        } catch (IOException e) {
            Log.d(TAG, "testEncodeReversal e = " + e.getMessage());
            e.printStackTrace();
        }
    }

    private static String bytesToHexCommonPrint(byte[] byteArray, int byteLength) {
        return bytesToHex(byteArray, byteLength, false, true, true);
    }

    private static String bytesToHex(byte[] byteArray, int byteLength, boolean prefix, boolean interval, boolean upperCase) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < byteArray.length && i < byteLength; i++) {
            String s = Integer.toHexString(byteArray[i] & 0xFF);
            if (s.length() < 2) {
                s = "0" + s;
            }
            if (upperCase) {
                s = s.toUpperCase();
            }
            if (prefix) {
                s = "0x" + s;
            }
            if (interval) {
                s += " ";
            }
            sb.append(s);
        }
        return interval ? sb.substring(0, sb.length() - 1) : sb.toString();
    }
}